import { createVNode, render } from 'vue';
import LoadingComponent from './LoadingComponent.vue';

const loadingDirective = {
  /**
   * 指令挂载时调用
   * @param {HTMLElement & { _loadingVnode?: VNode, _originalPosition?: string }} el 指令绑定的元素
   * @param {Object} binding 指令相关的信息对象
   */
  mounted(el, binding) {
    // 获取指令参数与修饰符
    const { value, modifiers } = binding;
    const rawModifiers = modifiers;
    const rawValue = typeof value === 'object' ? value : { show: value };

    // 确定fullscreen属性
    const fullscreen = rawModifiers.fullscreen || (rawValue && rawValue.fullscreen) || false;

    // 创建组件虚拟DOM
    const vNode = createVNode(LoadingComponent, {
      text: rawValue.text || '加载中...',
      background: rawValue.background || 'rgba(0, 0, 0, 0.7)',
      show: rawValue.show || false,
      fullscreen: fullscreen,
    });

    // 拷贝组件虚拟DOM到元素上
    el._loadingVnode = vNode;

    // 渲染loading组件
    if (fullscreen) {
      // 全屏模式：渲染到body
      render(vNode, document.body);
    } else {
      // 非全屏模式：确保目标元素相对定位
      el._originalPosition = el.style.position;
      if (
        el._originalPosition !== 'relative' &&
        el._originalPosition !== 'absolute' &&
        el._originalPosition !== 'fixed'
      ) {
        el.style.position = 'relative'; // 非定位元素默认设为相对定位
      }

      // 渲染到目标元素
      render(vNode, el);
    }

    // 禁止全局loading 页面滚动
    if (fullscreen) {
      document.body.style.overflow = 'hidden';
    }
  },

  /**
   * 指令更新时调用
   * @param {HTMLElement & { _loadingVnode?: VNode, _originalPosition?: string }} el 指令绑定的元素
   * @param {Object} binding 指令相关的信息对象
   */
  updated(el, binding) {
    // 获取指令参数与修饰符
    const { value } = binding;
    const rawValue = typeof value === 'object' ? value : { show: value };

    // 获取当前组件的fullscreen属性
    const fullscreen = el._loadingVnode?.component?.props?.fullscreen || false;

    // 更新组件虚拟DOM的show属性
    if (el._loadingVnode?.component) {
      el._loadingVnode.component.props.show = rawValue.show || false;
    }

    // 根据fullscreen属性选择正确的渲染目标
    if (fullscreen) {
      // 全屏模式：渲染到body
      render(el._loadingVnode, document.body);
    } else {
      // 非全屏模式：渲染到目标元素
      render(el._loadingVnode, el);
    }

    // 更新页面滚动状态
    if (fullscreen) {
      if (rawValue.show) {
        document.body.style.overflow = 'hidden';
      } else {
        document.body.style.overflow = 'auto';
      }
    }
  },

  /**
   * 指令卸载时调用
   * @param {HTMLElement & { _loadingVnode?: VNode, _originalPosition?: string }} el 指令绑定的元素
   */
  unmounted(el) {
    // 移除组件虚拟DOM
    render(null, el);

    // 恢复全局loading 页面滚动
    if (el._loadingVnode.component.props.fullscreen) {
      document.body.style.overflow = 'auto';
    }
  },
};

export default loadingDirective;
